package cn.elead.chaos.sso.server.web.login.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.elead.chaos.core.constant.Constants;
import cn.elead.chaos.core.util.StringUtils;
import cn.elead.chaos.framework.util.EnumUtil;
import cn.elead.chaos.framework.util.MessageUtils;
import cn.elead.chaos.sso.core.constant.SsoConstant;
import cn.elead.chaos.sso.core.user.LoginUser;
import cn.elead.chaos.sso.core.util.CookieUtil;
import cn.elead.chaos.sso.server.enums.ResponseType;
import cn.elead.chaos.sso.server.web.login.helper.SsoWebLoginHelper;
import cn.elead.chaos.sso.server.web.login.vo.Login;
import cn.elead.chaos.sso.server.web.system.domain.SsoClient;
import cn.elead.chaos.sso.server.web.system.domain.SysUser;
import cn.elead.chaos.sso.server.web.system.service.ISsoClientService;
import cn.elead.chaos.sso.server.web.system.service.ISysUserService;
import cn.elead.chaos.sso.server.web.system.service.impl.SysPasswordService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 传统项目单点登录(for web)
 * 
 * @author luopeng
 *
 */
@Controller
public class WebController extends LogController {

	@Autowired
	private SsoWebLoginHelper ssoWebLoginHelper;

	@Autowired
	private ISysUserService sysUserService;

	@Autowired
	private ISsoClientService ssoClientService;

	@Autowired
	private SysPasswordService sysPasswordService;

	/**
	 * 单点入口,用于校验当前用户是否登录
	 * <p>
	 * 如果登录,则重定向到单点客户端系统
	 * <p>
	 * 如果沒有登录,则重定向到登录页面
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(StrUtil.SLASH)
	public String index(RedirectAttributes attributes) {
		return SsoConstant.REDIRECT_URI_PREFIX + "/system/index";
	}

	/**
	 * 登录页面
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 */
	@GetMapping(SsoConstant.LOGIN_PAGE)
	public String login(Model model) {
		// 获取客户端信息
		String clientId = request.getParameter(SsoConstant.PARAM_CLIENT_ID);
		if (StrUtil.isBlank(clientId)) {
			ssoWebLoginHelper.setDefaultParam(model, request, null, "客户端ID不能为空");
			// 进入登录页面
			return ssoWebLoginHelper.toLoginPage(request);
		}
		// 获取客户端信息
		SsoClient client = ssoClientService.selectSsoClientById(clientId);
		if (ObjectUtil.isNull(client)) {
			// 默认参数
			ssoWebLoginHelper.setDefaultParam(model, request, null, "您好,客户端ID不正确,请先注册单点客户端信息!");
			// 进入登录页面
			return ssoWebLoginHelper.toLoginPage(request);
		}

		// 模式
		ResponseType responseType = EnumUtil.nameOf(ResponseType.class, request.getParameter(SsoConstant.PARAM_RESPONSE_TYPE));
		// 校验当前是否已经登录
		LoginUser user = ssoWebLoginHelper.loginCheck(request, response);
		if (ObjectUtil.isNull(user)) {
			ssoWebLoginHelper.setDefaultParam(model, request, client, request.getParameter(SsoConstant.ERROR_MSG));
			// 进入登录页面
			return ssoWebLoginHelper.toLoginPage(request, client.getTheme());
		} else {
			return ssoWebLoginHelper.redirectCodeCall(this, user, client, responseType, false);
		}
	}

	/**
	 * 登录
	 * <p>
	 * 如果登录,则重定向到单点客户端系统
	 * <P>
	 * 如果沒有登录,则重定向到登录页面
	 * <p>
	 * <a href="https://www.cnblogs.com/g-smile/p/9121335.html">关于重定向RedirectAttributes的用法<a/>
	 * 
	 * @param attributes
	 * @param Login
	 * @return
	 */
	@PostMapping(SsoConstant.LOGIN_PAGE)
	public String doLogin(RedirectAttributes attributes, Model model, Login login) {

		// 获取客户端信息
		String clientId = login.getClientId();
		if (StrUtil.isBlank(clientId)) {
			ssoWebLoginHelper.setDefaultParam(attributes, request, null, "客户端ID不能为空");
			// 进入登录页面
			return ssoWebLoginHelper.toLoginPage(request);
		}
		// 获取客户端信息
		SsoClient client = ssoClientService.selectSsoClientById(clientId);
		if (ObjectUtil.isNull(client)) {
			// 默认参数
			ssoWebLoginHelper.setDefaultParam(attributes, request, null, "您好,客户端ID不正确,请先注册单点客户端信息!");
			// 进入登录页面
			return ssoWebLoginHelper.toLoginPage(request);
		}

		// 校验用户和密码
		String url = ssoWebLoginHelper.vaildParam(request, attributes, model, client, login);
		if (ObjectUtil.isNotNull(url)) {
			return url;
		}
		// 查询出用户
		String username = login.getUsername();
		SysUser sysUser = sysUserService.selectUserByLoginName(login.getUsername());
		if (ObjectUtil.isNull(sysUser)) {
			recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists"));
			return ssoWebLoginHelper.redirectLogin(request, attributes, model, client, "用户不存在");
		}
		String password = login.getPassword();
		if (!sysPasswordService.matches(sysUser, password)) {
			recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"));
			return ssoWebLoginHelper.redirectLogin(request, attributes, model, client, "用户名密码错误");
		}
		if (StringUtils.equals(sysUser.getStatus(), "2")) {
			recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked"));
			return ssoWebLoginHelper.redirectLogin(request, attributes, model, client, "用户被禁用或是已离职");
		}

		LoginUser user = new LoginUser();
		user.setUserId(sysUser.getUserId());
		user.setLoginName(sysUser.getLoginName());
		user.setUserName(sysUser.getUserName());
		user.setEmail(sysUser.getEmail());
		user.setAvatar(sysUser.getAvatar());
		user.setDeptName(sysUser.getDept().getDeptName());
		
		// 缓存主题
		CookieUtil.set(response, SsoConstant.COOKIE_THEME, client.getTheme(), false);

		// 重定向到客户端系统
		return ssoWebLoginHelper.redirectCodeCall(this, user, login, client);

	}

	/**
	 * 退出登录
	 * <p>
	 * <a href="https://www.cnblogs.com/g-smile/p/9121335.html">关于重定向RedirectAttributes的用法<a/>
	 * 
	 * @param request
	 * @param attributes
	 * @return
	 */
	@RequestMapping(SsoConstant.SSO_LOGOUT)
	public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes attributes) {
		ssoWebLoginHelper.logout(request, response);
		// 重定向到登录页面
		return SsoConstant.REDIRECT_URI_PREFIX + StrUtil.SLASH + SsoConstant.LOGIN_PAGE;
	}

}